home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / Mail / Queue.php < prev    next >
PHP Script  |  2004-03-24  |  17KB  |  541 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Radek Maciaszek <chief@php.net>                             |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: Queue.php,v 1.13 2004/02/29 09:12:57 quipo Exp $
  20.  
  21. /**
  22. * Class for handle mail queue managment.
  23. * Wrapper for Pear::Mail and Pear::DB.
  24. * Could load, save and send saved mails in background
  25. * and also backup some mails.
  26. *
  27. * Mail queue class put mails in a temporary
  28. * container waiting to be fed to the MTA (Mail Transport Agent)
  29. * and send them later (eg. every few minutes) by crontab or in other way.
  30. *
  31. * -------------------------------------------------------------------------
  32. * A basic usage example:
  33. * -------------------------------------------------------------------------
  34. *
  35. * $container_options = array(
  36. *   'type'        => 'db',
  37. *   'database'    => 'dbname',
  38. *   'phptype'     => 'mysql',
  39. *   'username'    => 'root',
  40. *   'password'    => '',
  41. *   'mail_table'  => 'mail_queue'
  42. * );
  43. *   //optionally, a 'dns' string can be provided instead of db parameters.
  44. *   //look at DB::connect() method or at DB or MDB docs for details.
  45. *   //you could also use mdb container instead db
  46. *
  47. * $mail_options = array(
  48. *   'driver'   => 'smtp',
  49. *   'host'     => 'your_smtp_server.com',
  50. *   'port'     => 25,
  51. *   'auth'     => false,
  52. *   'username' => '',
  53. *   'password' => ''
  54. * );
  55. *
  56. * $mail_queue =& new Mail_Queue($container_options, $mail_options);
  57. * *****************************************************************
  58. * // Here the code differentiates wrt you want to add an email to the queue
  59. * // or you want to send the emails that already are in the queue.
  60. * *****************************************************************
  61. * // TO ADD AN EMAIL TO THE QUEUE
  62. * *****************************************************************
  63. * $from             = 'user@server.com';
  64. * $from_name        = 'admin';
  65. * $recipient        = 'recipient@other_server.com';
  66. * $recipient_name   = 'recipient';
  67. * $message          = 'Test message';
  68. * $from_params      = empty($from_name) ? '"'.$from_name.'" <'.$from.'>' : '<'.$from.'>';
  69. * $recipient_params = empty($recipient_name) ? '"'.$recipient_name.'" <'.$recipient.'>' : '<'.$recipient.'>';
  70. * $hdrs = array( 'From'    => $from_params,
  71. *                'To'      => $recipient_params,
  72. *                'Subject' => "test message body"  );
  73. * $mime =& new Mail_mime();
  74. * $mime->setTXTBody($message);
  75. * $body = $mime->get();
  76. * $hdrs = $mime->headers($hdrs);
  77. *
  78. * // Put message to queue
  79. * $mail_queue->put( $from, $recipient, $hdrs, $body );
  80. * //Also you could put this msg in more advanced mode [look at Mail_Queue docs for details]
  81. * $seconds_to_send = 3600;
  82. * $delete_after_send = false;
  83. * $id_user = 7;
  84. * $mail_queue->put( $from, $recipient, $hdrs, $body, $seconds_to_send, $delete_after_send, $id_user );
  85. *
  86. * *****************************************************************
  87. * // TO SEND EMAILS IN THE QUEUE
  88. * *****************************************************************
  89. * // How many mails could we send each time
  90. * $max_ammount_mails = 50;
  91. * $mail_queue =& new Mail_Queue($container_options, $mail_options);
  92. * $mail_queue->sendMailsInQueue($max_ammount_mails);
  93. * *****************************************************************
  94. *
  95. * // for more examples look to docs directory
  96. *
  97. * // end usage example
  98. * -------------------------------------------------------------------------
  99. *
  100. * @version $Revision: 1.13 $
  101. * $Id: Queue.php,v 1.13 2004/02/29 09:12:57 quipo Exp $
  102. * @author Radek Maciaszek <chief@php.net>
  103. */
  104.  
  105. /**
  106.  * This is special constant define start offset for limit sql queries to
  107.  * get mails.
  108.  */
  109. define('MAILQUEUE_START', 0);
  110.  
  111. /**
  112.  * You can specify how many mails will be loaded to
  113.  * queue else object use this constant for load all mails from db.
  114.  */
  115. define('MAILQUEUE_ALL', -1);
  116.  
  117. /**
  118.  * When you put new mail to queue you could specify user id who send e-mail.
  119.  * Else you could use system id: MAILQUEUE_SYSTEM or user unknown id: MAILQUEUE_UNKNOWN
  120.  */
  121. define('MAILQUEUE_SYSTEM',  -1);
  122. define('MAILQUEUE_UNKNOWN', -2);
  123.  
  124. /**
  125.  * This constant tells Mail_Queue how many times should try
  126.  * to send mails again if was any errors before.
  127.  */
  128. define('MAILQUEUE_TRY', 25);
  129.  
  130. /**
  131.  * MAILQUEUE_ERROR constants
  132.  */
  133. define('MAILQUEUE_ERROR',                   -1);
  134. define('MAILQUEUE_ERROR_NO_DRIVER',         -2);
  135. define('MAILQUEUE_ERROR_NO_CONTAINER',      -3);
  136. define('MAILQUEUE_ERROR_CANNOT_INITIALIZE', -4);
  137. define('MAILQUEUE_ERROR_NO_OPTIONS',        -5);
  138. define('MAILQUEUE_ERROR_CANNOT_CONNECT',    -6);
  139. define('MAILQUEUE_ERROR_QUERY_FAILED',      -7);
  140. define('MAILQUEUE_ERROR_UNEXPECTED',        -8);
  141. define('MAILQUEUE_ERROR_CANNOT_SEND_MAIL',  -9);
  142.  
  143. require_once 'PEAR.php';
  144. require_once 'Mail.php';
  145. require_once 'Mail/mime.php';
  146.  
  147.  
  148. /**
  149.  * Mail_Queue - base class for mail queue managment.
  150.  *
  151.  * @author   Radek Maciaszek <wodzu@tonet.pl>
  152.  * @version  $Id: Queue.php,v 1.13 2004/02/29 09:12:57 quipo Exp $
  153.  * @package  Mail_Queue
  154.  * @access   public
  155.  */
  156. class Mail_Queue extends PEAR
  157. {
  158.     // {{{ Class vars
  159.  
  160.     /**
  161.      * Mail options: smtp, mail etc. see Mail::factory
  162.      *
  163.      * @var array
  164.      */
  165.     var $mail_options;
  166.  
  167.     /**
  168.      * Mail_Queue_Container
  169.      *
  170.      * @var object
  171.      */
  172.     var $container;
  173.  
  174.     /**
  175.      * Reference to Pear_Mail object
  176.      *
  177.      * @var object
  178.      */
  179.     var $send_mail;
  180.  
  181.     /**
  182.      * Pear error mode (when raiseError is called)
  183.      * (see PEAR doc)
  184.      *
  185.      * @var int $_pearErrorMode
  186.      * @access private
  187.      */
  188.     var $pearErrorMode = PEAR_ERROR_RETURN;
  189.  
  190.     // }}}
  191.     // {{{ Mail_Queue
  192.  
  193.     /**
  194.      * Mail_Queue constructor
  195.      *
  196.      * @param  array $container_options  Mail_Queue container options
  197.      * @param  array $mail_options  How send mails.
  198.      *
  199.      * @return mixed  True on success else PEAR error class.
  200.      *
  201.      * @access public
  202.      */
  203.     function Mail_Queue($container_options, $mail_options)
  204.     {
  205.         $this->PEAR();
  206.         if (isset($mail_options['pearErrorMode'])) {
  207.             $this->pearErrorMode = $mail_options['pearErrorMode'];
  208.             // ugly hack to propagate 'pearErrorMode'
  209.             $container_options['pearErrorMode'] = $mail_options['pearErrorMode'];
  210.         }
  211.  
  212.         if (!is_array($mail_options) || !isset($mail_options['driver'])) {
  213.             return new Mail_Queue_Error(MAILQUEUE_ERROR_NO_DRIVER,
  214.                         $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__);
  215.         }
  216.         $this->mail_options = $mail_options;
  217.  
  218.         if (!is_array($container_options) || !isset($container_options['type'])) {
  219.             return new Mail_Queue_Error(MAILQUEUE_ERROR_NO_CONTAINER,
  220.                         $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__);
  221.         }
  222.         $container_type = strtolower($container_options['type']);
  223.         $container_class = 'Mail_Queue_Container_' . $container_type;
  224.         $container_classfile = $container_type . '.php';
  225.  
  226.         include_once 'Mail/Queue/Container/' . $container_classfile;
  227.         $this->container = new $container_class($container_options);
  228.         if(PEAR::isError($this->container)) {
  229.             return new Mail_Queue_Error(MAILQUEUE_ERROR_CANNOT_INITIALIZE,
  230.                         $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__);
  231.         }
  232.         return true;
  233.     }
  234.  
  235.     // }}}
  236.     // {{{ _Mail_Queue()
  237.  
  238.     /**
  239.      * Mail_Queue desctructor
  240.      *
  241.      * @return void
  242.      * @access public
  243.      */
  244.     function _Mail_Queue()
  245.     {
  246.         unset($this);
  247.     }
  248.  
  249.     // }}}
  250.     // {{{ factorySendMail()
  251.  
  252.     /**
  253.      * Provides an interface for generating Mail:: objects of various
  254.      * types see Mail::factory()
  255.      *
  256.      * @return void
  257.      *
  258.      * @access public
  259.      */
  260.     function factorySendMail()
  261.     {
  262.         $options = $this->mail_options;
  263.         unset($options['driver']);
  264.         $this->send_mail =& Mail::factory($this->mail_options['driver'], $options);
  265.     }
  266.  
  267.     // }}}
  268.     // {{{ setBufferSize()
  269.  
  270.     /**
  271.      * Keep memory usage under control. You can set the max number
  272.      * of mails that can be in the preload buffer at any given time.
  273.      * It won't limit the number of mails you can send, just the
  274.      * internal buffer size.
  275.      *
  276.      * @param integer $size  Optional - internal preload buffer size
  277.      **/
  278.     function setBufferSize($size = 10)
  279.     {
  280.         $this->container->buffer_size = $size;
  281.     }
  282.  
  283.  
  284.     // }}}
  285.     // {{{ sendMailsInQueue()
  286.  
  287.    /**
  288.      * Send mails fom queue.
  289.      *
  290.      * Mail_Queue::sendMailsInQueue()
  291.      *
  292.      * @param integer $limit     Optional - max limit mails send.
  293.      *                           This is the max number of emails send by
  294.      *                           this function.
  295.      * @param integer $offset    Optional - you could load mails from $offset (by id)
  296.      * @param integer $try       Optional - hoh many times mailqueu should try send
  297.      *                           each mail. If mail was sent succesful it will be delete
  298.      *                           from Mail_Queue.
  299.      * @return mixed  True on success else MAILQUEUE_ERROR object.
  300.      **/
  301.     function sendMailsInQueue($limit = MAILQUEUE_ALL, $offset = MAILQUEUE_START,
  302.                               $try = MAILQUEUE_TRY)
  303.     {
  304.         $this->container->setOption($limit, $offset, $try);
  305.         while ($mail = $this->get()) {
  306.             $this->container->countSend($mail);
  307.  
  308.             $result = $this->sendMail($mail);
  309.  
  310.             if (!PEAR::isError($result)) {
  311.                 $this->container->setAsSent($mail);
  312.                 if($mail->isDeleteAfterSend()) {
  313.                     $this->deleteMail($mail->getId());
  314.                 }
  315.             } else {
  316.                 PEAR::raiseError(
  317.                     MAILQUEUE_ERROR_CANNOT_SEND_MAIL, null, PEAR_ERROR_TRIGGER,
  318.                     E_USER_NOTICE, 'Error in sending mail: '.$result->getMessage());
  319.             }
  320.         }
  321.         return true;
  322.     }
  323.  
  324.     // }}}
  325.     // {{{ sendMailById()
  326.  
  327.     /**
  328.      * Send Mail by $id identifier. (bypass Mail_Queue)
  329.      *
  330.      * @param integer $id  Mail identifier
  331.      * @param  bool   $set_as_sent
  332.      * @return bool   true on success else false
  333.      *
  334.      * @access public
  335.      */
  336.     function sendMailById($id, $set_as_sent=true)
  337.     {
  338.         $mail =& $this->container->getMailById($id);
  339.         $sent = $this->sendMail($mail);
  340.         if ($sent and $set_as_sent) {
  341.             $this->container->setAsSent($mail);
  342.         }
  343.         return $sent;
  344.     }
  345.  
  346.     // }}}
  347.     // {{{ sendMail()
  348.  
  349.     /**
  350.      * Send mail from MailBody object
  351.      *
  352.      * @param object  MailBody object
  353.      * @return mixed  True on success else pear error class
  354.      *
  355.      * @access public
  356.      */
  357.     function sendMail($mail)
  358.     {
  359.         $recipient = $mail->getRecipient();
  360.         $hdrs = $mail->getHeaders();
  361.         $body = $mail->getBody();
  362.         if (empty($this->send_mail)) {
  363.             $this->factorySendMail();
  364.         }
  365.         return $this->send_mail->send($recipient, $hdrs, $body);
  366.     }
  367.  
  368.     // }}}
  369.     // {{{ get()
  370.  
  371.     /**
  372.      * Get next mail from queue. The emails are preloaded
  373.      * in a buffer for better performances.
  374.      *
  375.      * @return    object Mail_Queue_Container or error object
  376.      * @throw     MAILQUEUE_ERROR
  377.      * @access    public
  378.      */
  379.     function get()
  380.     {
  381.         return $this->container->get();
  382.     }
  383.  
  384.     // }}}
  385.     // {{{ put()
  386.  
  387.     /**
  388.      * Put new mail in queue.
  389.      *
  390.      * @see Mail_Queue_Container::put()
  391.      *
  392.      * @param string  $time_to_send  When mail have to be send
  393.      * @param integer $id_user  Sender id
  394.      * @param string  $ip    Sender ip
  395.      * @param string  $from  Sender e-mail
  396.      * @param string  $to    Reciepient e-mail
  397.      * @param string  $hdrs  Mail headers (in RFC)
  398.      * @param string  $body  Mail body (in RFC)
  399.      * @return mixed  ID of the record where this mail has been put
  400.      *                or Mail_Queue_Error on error
  401.      *
  402.      * @access public
  403.      **/
  404.     function put($from, $to, $hdrs, $body, $sec_to_send=0, $delete_after_send=true, $id_user=MAILQUEUE_SYSTEM)
  405.     {
  406.         $ip = getenv('REMOTE_ADDR');
  407.         $time_to_send = date("Y-m-d G:i:s", time() + $sec_to_send);
  408.         return $this->container->put( $time_to_send, $id_user,
  409.                             $ip, $from, $to, serialize($hdrs),
  410.                             serialize($body), $delete_after_send );
  411.     }
  412.  
  413.     // }}}
  414.     // {{{ deleteMail()
  415.  
  416.     /**
  417.      * Delete mail from queue database
  418.      *
  419.      * @param integer $id  Maila identifier
  420.      * @return boolean
  421.      *
  422.      * @access private
  423.      */
  424.     function deleteMail($id)
  425.     {
  426.         return $this->container->deleteMail($id);
  427.     }
  428.  
  429.     // }}}
  430.     // {{{ isError()
  431.  
  432.     /**
  433.      * Tell whether a result code from a Mail_Queue method is an error
  434.      *
  435.      * @param   int       $value  result code
  436.      * @return  boolean   whether $value is an MAILQUEUE_ERROR
  437.      * @access public
  438.      */
  439.     function isError($value)
  440.     {
  441.         return (is_object($value) && is_a($value, 'pear_error'));
  442.     }
  443.  
  444.     // }}}
  445.     // {{{ errorMessage()
  446.  
  447.     /**
  448.      * Return a textual error message for a MDB error code
  449.      *
  450.      * @param   int     $value error code
  451.      * @return  string  error message, or false if the error code was
  452.      *                  not recognized
  453.      * @access public
  454.      */
  455.     function errorMessage($value)
  456.     {
  457.         static $errorMessages;
  458.         if (!isset($errorMessages)) {
  459.             $errorMessages = array(
  460.                 MAILQUEUE_ERROR                    => 'unknown error',
  461.                 MAILQUEUE_ERROR_NO_DRIVER          => 'No mail driver specified',
  462.                 MAILQUEUE_ERROR_NO_CONTAINER       => 'No container specified',
  463.                 MAILQUEUE_ERROR_CANNOT_INITIALIZE  => 'Cannot initialize container',
  464.                 MAILQUEUE_ERROR_NO_OPTIONS         => 'No container options specified',
  465.                 MAILQUEUE_ERROR_CANNOT_CONNECT     => 'Cannot connect to database',
  466.                 MAILQUEUE_ERROR_QUERY_FAILED       => 'db query failed',
  467.                 MAILQUEUE_ERROR_UNEXPECTED         => 'Unexpected class',
  468.                 MAILQUEUE_ERROR_CANNOT_SEND_MAIL   => 'Cannot send email',
  469.             );
  470.         }
  471.  
  472.         if (Mail_Queue::isError($value)) {
  473.             $value = $value->getCode();
  474.         }
  475.  
  476.         return(isset($errorMessages[$value]) ?
  477.            $errorMessages[$value] : $errorMessages[MAILQUEUE_ERROR]);
  478.     }
  479.  
  480.     // }}}
  481. /*
  482.     function raiseError($msg, $code = null, $file = null, $line = null, $mode = null)
  483.     {
  484.         if ($file !== null) {
  485.             $err = PEAR::raiseError(sprintf("%s [%s on line %d].", $msg, $file, $line), $code, $mode);
  486.         } else {
  487.             $err = PEAR::raiseError(sprintf("%s", $msg), $code, $mode);
  488.         }
  489. á á á á return $err;
  490.     }
  491. */
  492. }
  493.  
  494.  
  495.  
  496.  
  497. /**
  498.  * Mail_Queue_Error implements a class for reporting error
  499.  * messages.
  500.  *
  501.  * @package Mail_Queue
  502.  * @category Mail
  503.  */
  504. class Mail_Queue_Error extends PEAR_Error
  505. {
  506.     /**
  507.      * Prefix for all error messages
  508.     *
  509.      * @access private
  510.      * @var    string
  511.      */
  512.     var $error_message_prefix = 'Mail Queue Error: ';
  513.  
  514.     // {{{ constructor
  515.  
  516.     /**
  517.      * Mail_Queue_Error constructor.
  518.      *
  519.      * @param mixed   $code      Mail_Queue error code, or string with error message.
  520.      * @param integer $mode      what 'error mode' to operate in
  521.      * @param integer $level     what error level to use for
  522.      *                           $mode & PEAR_ERROR_TRIGGER
  523.      * @param string  $debuginfo additional debug info
  524.      */
  525.     function Mail_Queue_Error($code = MAILQUEUE_ERROR, $mode = PEAR_ERROR_RETURN,
  526.               $level = E_USER_NOTICE,  $file=__FILE__, $line=__LINE__, $debuginfo='')
  527.     {
  528.  
  529.         $debuginfo .= (empty($debuginfo) ? '' : ' - '). 'FILE: '.$file.', LINE: '.$line;
  530.         if (is_int($code)) {
  531.             $this->PEAR_Error('Mail Queue Error: '.Mail_Queue::errorMessage($code),
  532.                               $code, $mode, $level, $debuginfo);
  533.         } else {
  534.             $this->PEAR_Error('Mail Queue Error: '.$code, MAILQUEUE_ERROR, $mode,
  535.                               $level, $debuginfo);
  536.         }
  537.     }
  538.  
  539.     // }}}
  540. }
  541. ?>